package ch1.waitandnotify;

/**
 * 类说明：快递实体类,用来示范等待和通知
 *
 * 面试题：采用java多线程技术（例如wait和nofify），设计实现一个符合生产者和消费者问题的程序
 * 对一把枪进行操作，生产者线程是装子弹，消费者线程是发射子弹。 子弹满了不能装子弹，子弹空了不能发子弹（包子铺卖包子一样）
 */
public class Express {
    //静态常量
    public final static String CITY = "ShangHai";
    //快递里程数
    private int km;
    //快递到达地点
    private String site;

    public Express() {
    }

    public Express(int km, String site) {
        this.km = km;
        this.site = site;
    }

    /* 变化公里数，通知处于wait状态并需要处理公里数的线程进行业务处理*/
    public synchronized void changeKm() {
        this.km = 101;
        notify();
    }

    /* 变化地点，通知处于wait状态并需要处理地点的线程进行业务处理*/
    public synchronized void changeSite() {
        this.site = "BeiJing";
        notifyAll();
    }

    /**
     * 等待公里变化
     */
    public synchronized void waitKm() {
        while (this.km < 100) {
            try {
                wait();
                System.out.println("Check Site thread[" + Thread.currentThread().getId() + "] is be notified");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("the Km is " + this.km + ",I will change db");
    }


    /**
     * 等待目的地变化
     */
    public synchronized void waitSite() {
        while (this.site.equals(CITY)) {
            try {
                wait();
                System.out.println("Check Site thread[" + Thread.currentThread().getId() + "] is be notified");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("the site is " + this.site + ",I will call user");
    }
}
